﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using DataTransferObject;
using Presenter.TaskFunctionalPresenter;
using DevComponents.DotNetBar;
using DevComponents.DotNetBar.Controls;
using IView.ITaskFunctional;
using System.Windows.Forms;
using System.Drawing;
using Outlook = Microsoft.Office.Interop.Outlook;


namespace JSKE.TaskFunctionalForm
{
    public partial class TaskManagerForm : Office2007Form , ITaskManager
    {
        #region Attributes
        private PresenterTaskManagerForm _presenter;
        private ViewStates _viewState;

        private List<Task> jskeTaskList = new List<Task>();
        #endregion

        #region Constructor
        public TaskManagerForm()
        {
            InitializeComponent();
            _presenter = new PresenterTaskManagerForm(this, Properties.Settings.Default.DataMode);
            _viewState = ViewStates.NormalView;

        }
        #endregion

        #region Properties
        /// <summary>
        /// Trả về List các <seealso cref="Task"/> của người dùng, List này là List các Task của JskeEngine và cũng được lưu trong thuộc tính Tag của listViewMytag
        /// </summary>
        /// <value>The list of my task.</value>
        public List<Task> ListOfMyTask
        {
            get
            {
                return listViewMytask.Tag as List<Task>;
            }
        }
        #endregion

        #region ITaskManager members
        /// <summary>
        /// Thực hiện việc xuất ra danh sách các task ra listViewMyTask. Các subitem của ListViewItem mặc định sẽ theo danh sách của PresenterTaskManagerForm.DETAIL_COLUMNS
        /// </summary>
        /// <param name="tasks">The tasks.</param>
        public void PopulaterMyTasks(List<Task> tasks)
        {
            InitializeColumnForListView(PresenterTaskManagerForm.DETAIL_COLUMNS, PresenterTaskManagerForm.COLUMNS_WIDTH);
            listViewMytask.Tag = tasks;
            foreach (Task task in tasks)
            {
                // thứ tự các thêm SubItem phải phù hợp với thứ tự PresenterTaskManagerForm.DETAIL_COLUMNS
                ListViewItem newListViewItem = new ListViewItem(task.Name);
                newListViewItem.SubItems.Add(task.TotalWork + "");
                newListViewItem.SubItems.Add(task.Priority + "");
                newListViewItem.Tag = task;
                if (task.ScheduledStartDate == DateTime.MinValue)
                {
                    newListViewItem.SubItems.Add(string.Empty);
                }
                else
                {
                    newListViewItem.SubItems.Add(task.ScheduledEndDate.ToString());
                }

                if (task.ScheduledEndDate == DateTime.MinValue)
                {
                    newListViewItem.SubItems.Add(string.Empty);
                }
                else
                {
                    newListViewItem.SubItems.Add(task.ScheduledEndDate.ToString());
                }
                listViewMytask.Items.Add(newListViewItem);
            }
        }

        /// <summary>
        /// Group các task trong MyTaskListView theo Project
        /// </summary>
        public void ViewTaskByProject()
        {
            listViewMytask.ShowGroups = true;
            List<ListViewGroup> groups = _presenter.GroupOfProjects();
            listViewMytask.Groups.Clear();
            listViewMytask.Groups.AddRange(groups.ToArray());
            foreach (ListViewItem item in listViewMytask.Items)
            {
                item.Group = null;
                Task itemTask = item.Tag as Task;
                foreach (ListViewGroup group in listViewMytask.Groups)
                {
                    if (group.Header.Equals(itemTask.ProjectName))
                    {
                        item.Group = group;
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// VGroup các task trong MyTaskListView theo Working hour
        /// </summary>
        public void ViewTaskByWorkingHour()
        {
            listViewMytask.ShowGroups = true;
            List<ListViewGroup> groups = _presenter.GroupOfWorkingHour();
            listViewMytask.Groups.Clear();
            listViewMytask.Groups.AddRange(groups.ToArray());
            foreach (ListViewItem item in listViewMytask.Items)
            {
                item.Group = null;
                Task itemTask = item.Tag as Task;
                foreach (ListViewGroup group in listViewMytask.Groups)
                {
                    if (((int)group.Tag) == itemTask.WorkingHourID)
                    {
                        item.Group = group;
                        break;
                    }
                }
            }
        }
        #endregion

        #region Private, Protected methods
        /// <summary>
        /// Khởi tạo các column headers cho ListView (ListView hiển thị dưới style Details).
        /// Sau này sẽ xem xét việc cho người dùng thêm bớt số column cho phù hợp với cách hiển thị mà người dùng mong muốn
        /// </summary>
        /// <param name="columns">The columns.</param>
        /// <param name="widths">The widths.</param>
        protected void InitializeColumnForListView(string[] columns, int[] widths)
        {
            
            ColumnHeader[] columnHeadersMyTasks = new ColumnHeader[columns.Length];
            ColumnHeader[] columnHeadersOutlookTasks = new ColumnHeader[columns.Length];
            for (int i = 0; i < columns.Length; i++)
            {
                ColumnHeader newColumn = new ColumnHeader();
                newColumn.Text = columns[i];
                columnHeadersMyTasks[i] = newColumn;
                columnHeadersOutlookTasks[i] = newColumn.Clone() as ColumnHeader;
            }
            if (widths == null)
            {
                listViewMytask.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
                listViewOutlookTask.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
            }
            else
            {
                for (int i = 0; i < widths.Length; i++)
                {
                    columnHeadersMyTasks[i].Width = widths[i];
                    columnHeadersOutlookTasks[i].Width = widths[i];
                }
            }
            
            listViewMytask.Columns.AddRange(columnHeadersMyTasks);
            
            listViewOutlookTask.Columns.AddRange(columnHeadersOutlookTasks);
        }


        /// <summary>
        /// Dùng để tìm ListViewItem gần Mouse Cursor nhất khi drag-and-drop (Position của mouse cursor là relative position so với ListView, 
        /// không phải so với screen)
        /// </summary>
        /// <param name="listView">The list view.</param>
        /// <returns></returns>
        protected ListViewItem GetTheClosestListViewItem(ListView listView, Point p)
        {
            double minValueDistance = double.MaxValue;
            ListViewItem closestItem = null;
            foreach (ListViewItem listViewItem in listView.Items)
            {
                Point itemPosition = listViewItem.Position;
                // công thức tính khỏang cách không cần lầy căn vì mục đích hàm chỉ cần tìm ListViewItem gần nhất
                double distance = Math.Pow(itemPosition.X - p.X, 2) + Math.Pow(itemPosition.Y - p.Y, 2);
                if (minValueDistance > distance)
                {
                    closestItem = listViewItem;
                    minValueDistance = distance;
                }
            }
            return closestItem;
        }
        #endregion

        #region Event Handlers
        private void chkBoxProject_CheckedChanged(object sender, EventArgs e)
        {
            if (chkBoxProject.Checked == true)
            {
                _viewState = ViewStates.ViewByProject;
                ViewTaskByProject();
            }
        }

        private void chkBoxWorkingHour_CheckedChanged(object sender, EventArgs e)
        {
            if (chkBoxWorkingHour.Checked == true)
            {
                _viewState = ViewStates.ViewByWorkingHour;
                ViewTaskByWorkingHour();
            }
        }

        private void chkBoxDetail_CheckedChanged(object sender, EventArgs e)
        {
            if (chkBoxDetail.Checked == true)
            {
                _viewState = ViewStates.NormalView;
                listViewMytask.ShowGroups = false;
            }
        }

        private void butImport_Click(object sender, EventArgs e)
        {
            Outlook.Application OutLookObj = new Outlook.Application();
            Outlook.MAPIFolder fldTask = (Outlook.MAPIFolder)OutLookObj.Session.PickFolder();
            #region Import task to ListView outlook tasks
            if (fldTask != null)
            {
                List<Outlook.TaskItem> outlookTasks = new List<Outlook.TaskItem>();
                foreach (Outlook.TaskItem taskItem in fldTask.Items)
                {
                    outlookTasks.Add(taskItem);
                    /*Outlook.UserProperties up = taskItem.UserProperties;
                    System.Collections.IEnumerator enumerator = up.GetEnumerator();
                    List<Outlook.UserProperty> userProperties = new List<Outlook.UserProperty>();
                    while (enumerator.MoveNext())
                    {
                        userProperties.Add(enumerator.Current as Outlook.UserProperty);
                    }*/
                    ListViewItem newListViewItem = new ListViewItem(taskItem.Subject);
                    newListViewItem.SubItems.Add(taskItem.TotalWork + "");
                    newListViewItem.SubItems.Add(taskItem.SchedulePlusPriority + "");
                    newListViewItem.Tag = taskItem;
                    listViewOutlookTask.Items.Add(newListViewItem);
                }
            }
            #endregion
            listViewOutlookTask.Focus();
        }

        private void listViewOutlookTask_ItemDrag(object sender, ItemDragEventArgs e)
        {
            listViewOutlookTask.DoDragDrop(listViewOutlookTask.SelectedItems, DragDropEffects.Copy);
        }

        private void listViewMytask_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(ListView.SelectedListViewItemCollection)))
            {
                e.Effect = DragDropEffects.Copy;
            }
        }

        private void listViewMytask_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(ListView.SelectedListViewItemCollection)))
            {
                ListView.SelectedListViewItemCollection dragedItems = e.Data.GetData(typeof(ListView.SelectedListViewItemCollection)) as ListView.SelectedListViewItemCollection;
                foreach (ListViewItem dragedItem in dragedItems)
                {
                    if (dragedItem.Tag is Outlook.TaskItem)
                    {
                        Outlook.TaskItem outlookTask = dragedItem.Tag as Outlook.TaskItem;
                        Point targetPoint = listViewMytask.PointToClient(new Point(e.X, e.Y));
                        ListViewItem itemNearCursor = null;
                        itemNearCursor = this.GetTheClosestListViewItem(listViewMytask, targetPoint);
                        Task newTask = new Task(outlookTask.Subject, 1, outlookTask.TotalWork);
                        if (itemNearCursor != null)
                        {
                            if (_viewState == ViewStates.ViewByProject)
                            {
                                Task taskInSameGroup = itemNearCursor.Tag as Task;
                                newTask.ProjectName = taskInSameGroup.ProjectName;
                            }
                            else if (_viewState == ViewStates.ViewByWorkingHour)
                            {
                                Task taskInSameGroup = itemNearCursor.Tag as Task;
                                newTask.WorkingHourID = taskInSameGroup.WorkingHourID;
                            }
                            _presenter.AddTaskToEngine(newTask);
                            ListViewItem newListViewItem = new ListViewItem(newTask.Name);
                            newListViewItem.SubItems.Add(newTask.TotalWork + "");
                            newListViewItem.SubItems.Add(newTask.Priority + "");
                            newListViewItem.SubItems.Add(string.Empty); // add ScheduledStartDate - nếu không khi edit Item này sẽ gây ra lỗi
                            newListViewItem.SubItems.Add(string.Empty); // add ScheduledEndDate
                            newListViewItem.Tag = newTask;
                            newListViewItem.Group = itemNearCursor.Group;
                            listViewMytask.Items.Add(newListViewItem);
                        }
                        else
                        {
                            _presenter.AddTaskToEngine(newTask);
                            ListViewItem newListViewItem = new ListViewItem(newTask.Name);
                            newListViewItem.SubItems.Add(newTask.TotalWork + "");
                            newListViewItem.SubItems.Add(newTask.Priority + "");
                            newListViewItem.SubItems.Add(string.Empty); // add ScheduledStartDate - nếu không khi edit Item này sẽ gây ra lỗi
                            newListViewItem.SubItems.Add(string.Empty); // add ScheduledEndDate
                            newListViewItem.Tag = newTask;
                            listViewMytask.Items.Add(newListViewItem);
                        }
                    }
                }
            }
        }

        private void listViewMytask_ItemActivate(object sender, EventArgs e)
        {
            ListViewItem editingListViewItem = listViewMytask.SelectedItems[0];
            TaskForm editTaskForm = new TaskForm(listViewMytask.SelectedItems[0].Tag as Task);
            editTaskForm.ShowDialog();
            Task editedTask = editingListViewItem.Tag as Task;;
            editingListViewItem.Text = editedTask.Name;

            editingListViewItem.SubItems[1].Text = editedTask.TotalWork + "";
            editingListViewItem.SubItems[2].Text = editedTask.Priority + "";
            editingListViewItem.Tag = editedTask;
            if (editedTask.ScheduledStartDate == DateTime.MinValue)
            {
                editingListViewItem.SubItems[3].Text = string.Empty;
            }
            else
            {
                editingListViewItem.SubItems[3].Text = editedTask.ScheduledEndDate.ToString();
            }

            if (editedTask.ScheduledEndDate == DateTime.MinValue)
            {
                editingListViewItem.SubItems[4].Text = string.Empty;
            }
            else
            {
                editingListViewItem.SubItems[4].Text = editedTask.ScheduledEndDate.ToString();
            }
        }
        #endregion


        internal enum ViewStates
        {
            ViewByProject, ViewByWorkingHour, NormalView
        };


    }
}
